package com.yuntsg.subject_database.servic;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.yuntsg.subject_database.util.EsClient;
import com.yuntsg.subject_database.util.StringUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * ZFL
 * 13864677931
 * 2690370788@qq.com
 * 2023-02-10
 */
public class AllQueryBasicService {

    public static ElasticsearchClient client = EsClient.client();

    /**
     * 指定返回数量
     *
     * @param index    索引名称
     * @param query    检索条件
     * @param from     当前页
     * @param size     每页显示数量
     * @param includes 要返回的字段
     * @param cla      以Bean类型接收
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<Hit<T>> allQuery(String index, Query query, Integer from, Integer size, List<String> includes, Class<T> cla) throws IOException {
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index)
                .query(query)
                .from(from).size(size);
        if (includes != null) {
            builder.source(sourceConfigBuilder -> sourceConfigBuilder
                    .filter(sourceFilterBuilder -> sourceFilterBuilder
                            .includes(includes)));
        }
        SearchResponse<T> response = client.search(builder.build(), cla);
        List<Hit<T>> hits = response.hits().hits();
        return hits;
    }

    /**
     * 带排序
     *
     * @param index
     * @param query
     * @param from
     * @param size
     * @param includes
     * @param shortBy
     * @param shortType
     * @param cla
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<Hit<T>> allQueryShort(String index, Query query, Integer from, Integer size, List<String> includes, String shortBy, Integer shortType, Class<T> cla) throws IOException {
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index)
                .query(query)
                .from(from).size(size);
        if (includes != null) {
            builder.source(sourceConfigBuilder -> sourceConfigBuilder
                    .filter(sourceFilterBuilder -> sourceFilterBuilder
                            .includes(includes)));
        }
        if (!StringUtil.isEmpty(shortBy)) {
            builder.sort(sortOptionsBuilder -> sortOptionsBuilder
                    .field(fieldSortBuilder -> fieldSortBuilder
                            .field(shortBy).order(shortType == 0 ? SortOrder.Asc : SortOrder.Desc)));
        }
        SearchResponse<T> response = client.search(builder.build(), cla);
        List<Hit<T>> hits = response.hits().hits();
        return hits;
    }

    /**
     * 返回response ,通常需要手动处理分页的时候进行
     * long value = response.hits().total().value();
     * 这个可以获取到命中条数
     *
     * @param index
     * @param query
     * @param from
     * @param size
     * @param includes
     * @param cla
     * @return
     * @throws IOException
     */
    public static <T> SearchResponse<T> allQueryRes(String index, Query query, Integer from, Integer size, List<String> includes, Class<T> cla) throws IOException {
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index)
                .query(query)
                .trackTotalHits(k -> k.enabled(true))
                .from(from).size(size);
        if (includes != null) {
            builder.source(sourceConfigBuilder -> sourceConfigBuilder
                    .filter(sourceFilterBuilder -> sourceFilterBuilder
                            .includes(includes)));
        }

        return client.search(builder.build(), cla);
    }

    /**
     * 默认返回前十个
     *
     * @param index
     * @param query
     * @param includes
     * @param cla
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<Hit<T>> allQuery(String index, Query query, List<String> includes, Class<T> cla) throws IOException {
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index)
                .query(query)
                .from(0).size(10);
        if (includes != null) {
            builder.source(sourceConfigBuilder -> sourceConfigBuilder
                    .filter(sourceFilterBuilder -> sourceFilterBuilder
                            .includes(includes)));
        }
        SearchResponse<T> response = client.search(builder.build(), cla);
        List<Hit<T>> hits = response.hits().hits();
        return hits;
    }


    public static <T> List<T> coventList(List<Hit<T>> hits) {
        List<T> collect = hits.stream().map(i -> i.source()).collect(toList());
        return collect;
    }



    /**
     * 分页
     *
     * @param page
     * @param limit
     * @return
     */
    public static List<Integer> checkPage(Integer page, Integer limit) {
        if (page == null) page = 0;
        if (limit == null) limit = 10;
        List<Integer> list = new ArrayList<>();

        list.add((page - 1) * limit);
        //list.add(((page - 1) * limit) + limit);
        list.add(limit);
        return list;
    }



}
